package com.tjhk.java.tech;

import sun.misc.Launcher;
import java.net.URL;

public class ClassLoaderTest {
    public static void main(String[] args) {
        /**
         * 引导类加载器负责加载系统类（通常从JAR文件tr.jar中进行加载），而且通常是C语言实现的，引导类加载器没有对应的ClassLoader对象
         */
        /**
         * 扩展类加载器是从jre/lib/ext中加载“标准扩展”，可以将JAR文件放入该目录，这样即使没有任何类路径，扩展类加载器也可以找到其中的各个类
         * JAVA实现 是URLClassLoader类的实例
         */

        /**
         * 系统类加载器用于加载应用类。在由CLASSPATH环境变量或者-classpath命令行选项设置的目录中或者JAR/ZIP文件中查找
         * JAVA实现 是URLClassLoader类的实例
         */
        /*** 除引导类加载器外 父/子关系，双亲委派 先加载父类加载器，加载失败加载给定类加载器 ***/
        // 加载过程
        // BootstrapClassLoader(引导类加载器)加载核心jar
        // 由于BootstrapClassLoader对Java不可见,所以返回了null,我们也可以通过某一个类的加载器是否为null来作为判断该类是不是使用BootstrapClassLoader进行加载的依据
        /**
         * 称为启动类加载器，是Java类加载层次中最顶层的类加载器，负责加载JDK中的核心类库，
         * 如：rt.jar、resources.jar、charsets.jar等，可通过如下程序获得该类加载器从哪些地方加载了相关的jar或class文件
         */
        ClassLoader c = Launcher.class.getClassLoader();
        System.out.println(c);

        URL[] urLs = Launcher.getBootstrapClassPath().getURLs();
        for (URL url : urLs) {
            System.out.println("BootstrapClass:"+url.toExternalForm());
        }

        // Launcher rt.jar ExtClassLoader、AppClassLoader是内部类
        // 创建首先创建ExtClassLoader，然后将ExtClassLoader作为父类加载器创建AppClassLoader，两者都继承了URLClassLoader
        /**
         *  public Launcher() {
         *         Launcher.ExtClassLoader var1;
         *         // 创建ExtClassLoader
         *         try {
         *             var1 = Launcher.ExtClassLoader.getExtClassLoader();
         *         } catch (IOException var10) {
         *             throw new InternalError("Could not create extension class loader", var10);
         *         }
         *         // 创建AppClassLoader 并将ExtClassLoader作为父类加载器
         *         try {
         *             this.loader = Launcher.AppClassLoader.getAppClassLoader(var1);
         *         } catch (IOException var9) {
         *             throw new InternalError("Could not create application class loader", var9);
         *         }
         *         // 设置主线程的ClassLoader为AppClassLoader
         *         Thread.currentThread().setContextClassLoader(this.loader);
         *         // 配置安全管理器
         *         String var2 = System.getProperty("java.security.manager");
         *         if (var2 != null) {
         *             SecurityManager var3 = null;
         *             if (!"".equals(var2) && !"default".equals(var2)) {
         *                 try {
         *                     var3 = (SecurityManager)this.loader.loadClass(var2).newInstance();
         *                 } catch (IllegalAccessException var5) {
         *                 } catch (InstantiationException var6) {
         *                 } catch (ClassNotFoundException var7) {
         *                 } catch (ClassCastException var8) {
         *                 }
         *             } else {
         *                 var3 = new SecurityManager();
         *             }
         *
         *             if (var3 == null) {
         *                 throw new InternalError("Could not create SecurityManager: " + var2);
         *             }
         *
         *             System.setSecurityManager(var3);
         *         }
         *  }
         *          // ExtClassLoader 设置父类加载器为null
         *         public ExtClassLoader(File[] var1) throws IOException {
         *             super(getExtURLs(var1), (ClassLoader)null, Launcher.factory);
         *             SharedSecrets.getJavaNetAccess().getURLClassPath(this).initLookupCache(this);
         *         }
         */
        System.out.println("AppClassLoader:"+ClassLoader.getSystemClassLoader());
        System.out.println(Thread.currentThread().getContextClassLoader());
        String classPath = System.getProperty("java.class.path");
        for (String path : classPath.split(";")) {
            System.out.println(path);
        }

        /**
         * 获取堆栈轨迹数组
         */
        StackTraceElement[] element = Thread.currentThread().getStackTrace();
        for (int i = 0 ;i < element.length; i++){
            System.out.println(element[i]);
        }

    }
}
